package com.ev.apis.controller.asl;

import cn.afterturn.easypoi.entity.vo.TemplateExcelConstants;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import cn.afterturn.easypoi.view.PoiBaseView;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ev.apis.model.DsResultResponse;
import com.ev.asl.constant.AslConstant;
import com.ev.asl.dao.AssemblyDailyDao;
import com.ev.asl.dao.CheckResultDao;
import com.ev.asl.dao.CheckResultDetailDao;
import com.ev.asl.domain.*;
import com.ev.asl.dto.*;
import com.ev.asl.service.AssemblyDailyService;
import com.ev.asl.service.AssemblyInstructionService;
import com.ev.asl.service.CheckResultService;
import com.ev.asl.service.MoldingBarcodeService;
import com.ev.asl.vo.CheckResultDetail2VO;
import com.ev.custom.service.NoticeService;
import com.ev.framework.annotation.EvApiByToken;
import com.ev.framework.config.Constant;
import com.ev.framework.config.ConstantForMES;
import com.ev.framework.utils.*;
import com.ev.mes.service.CheckProjectService;
import com.ev.system.domain.UserDO;
import com.ev.system.service.UserService;
import com.google.common.collect.Maps;
import io.swagger.annotations.*;
import lombok.extern.java.Log;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 组装日报API
 *
 * @author 姚家乐
 * @since 2021/5/26 9:57
 */
@Api(value = "/", tags = "组装日报API")
@RestController
@Slf4j
public class AssemblyDailyApiController {

    @Autowired
    private AssemblyDailyDao dao;
    @Autowired
    private AssemblyDailyService service;
    @Autowired
    private AssemblyInstructionService assemblyInstructionService;
    @Autowired
    private CheckResultDao checkResultDao;
    @Autowired
    private CheckResultDetailDao checkResultDetailDao;

    @Autowired
    private CheckProjectService checkProjectService;
    @Autowired
    private CheckResultService checkResultService;
    @Autowired
    private MoldingBarcodeService moldingBarcodeService;

    @Autowired
    private NoticeService noticeService;

    @Autowired
    private UserService userService;

//
//    @EvApiByToken(value = "/apis/AssemblyDaily/dddddd", method = RequestMethod.GET, apiTitle = "查看组装日报详情")
//    @ApiOperation("查看组装日报详情")
//    public R dddddddd() {
//        return R.ok(moldingBarcodeService.generatingStreamCode(950).toString());
//    }


    /**
     * 保存组装生产指示信息
     *
     * @date 2019-11-27
     * @author gumingjie
     */
    @Transactional(rollbackFor = Exception.class)
    @EvApiByToken(value = "/apis/AssemblyDaily/save", method = RequestMethod.POST, apiTitle = "保存成型生产指示信息")
    @ApiOperation("保存组装生产指示信息")
    @ApiImplicitParams({@ApiImplicitParam(name = "indicateDate", value = "日期", dataType = "Date"),
            @ApiImplicitParam(name = "startTime1", value = "", dataType = "String"),
            @ApiImplicitParam(name = "startTime2", value = "", dataType = "String"),
            @ApiImplicitParam(name = "startTime3", value = "", dataType = "String"),
            @ApiImplicitParam(name = "startTime4", value = "", dataType = "String"),
            @ApiImplicitParam(name = "startTime5", value = "", dataType = "String"),
            @ApiImplicitParam(name = "startTime6", value = "", dataType = "String"),
            @ApiImplicitParam(name = "endTime1", value = "", dataType = "String"),
            @ApiImplicitParam(name = "endTime2", value = "", dataType = "String"),
            @ApiImplicitParam(name = "endTime3", value = "", dataType = "String"),
            @ApiImplicitParam(name = "endTime4", value = "", dataType = "String"),
            @ApiImplicitParam(name = "endTime5", value = "", dataType = "String"),
            @ApiImplicitParam(name = "endTime6", value = "", dataType = "String"),
            @ApiImplicitParam(name = "thing1", value = "", dataType = "String"),
            @ApiImplicitParam(name = "thing2", value = "", dataType = "String"),
            @ApiImplicitParam(name = "thing3", value = "", dataType = "String"),
            @ApiImplicitParam(name = "aiId", value = "组装指示主键id", dataType = "int"),
            @ApiImplicitParam(name = "aiNo", value = "组装指示编号", dataType = "String"),
            @ApiImplicitParam(name = "productionQty", value = "生产数量", dataType = "Number"),
            @ApiImplicitParam(name = "qualifiedQty", value = "合格数量", dataType = "Number"),
            @ApiImplicitParam(name = "inspectionQty", value = "不良数量", dataType = "Number"),
            @ApiImplicitParam(name = "badType", value = "不良类型（数据字典维护）", dataType = "init"),
            @ApiImplicitParam(name = "feedingMaterial", value = "（List<>产品代码（子件），产品名称（子件），规格型号，使用数量（EA），不良数量（EA），不良类型，未达要因）", dataType = "JSON"),
            @ApiImplicitParam(name = "specialNoteItem", value = "特记事项", dataType = "String")})
    public R save(AssemblyDailyDto dto) {
//        Map<String,Object> param = new HashMap<>();
//        param.put("isChooseShow",AslConstant.TWO);
//        param.put("instructionId",dto.getAiId());
//        List<Map<String, Object>> list = checkResultService.listForMap(param);
//        if (ObjectUtils.isEmpty(list) || list.size() == 0){
//            return R.error("该指示书不存在首检报告，不允许新增日报");
//        }
//        Map<String,Object> resu = list.get(0);
//
//        Integer n = Integer.parseInt(String.valueOf(resu.get("result")));
//        if (AslConstant.ONE.equals(n)){
//            return R.error("选中的指示书首检不合格，不允许新增日报");
//        }
//        if (ObjectUtils.isEmpty(list) || list.size() == 0){
//            return R.error("该指示书不存在首检报告，不允许新增日报");
//        }

        AssemblyInstructionDO instructionDO = assemblyInstructionService.get(dto.getAiId());

//        Map<String,Object> param = new HashMap<>();
//        param.put("isChooseShow",AslConstant.TWO);
//        param.put("instructionId",dto.getAiId());
//        List<Map<String, Object>> list = checkResultService.listForMap(param);
//        String indicateDate = DateUtils.format(dto.getIndicateDate());

//        if (!ObjectUtils.isEmpty(list)){
//            List<Map<String, Object>> todayResult = list.stream()
//                    .filter(result -> !ObjectUtils.isEmpty(result.get("productionDate")) && DateUtils.format((Date) result.get("productionDate")).equals(indicateDate)).collect(Collectors.toList());
//            if (!ObjectUtils.isEmpty(todayResult)){
//                return R.error("该指示书今天已生成检验报告，不允许新增日报");
//            }
//        }
        Map<String, Object> result = Maps.newHashMapWithExpectedSize(1);
        if (service.save(dto) > 0) {
            result.put("id", dto.getId());
        }
        //生成检验书
        Map<String, Object> params2 = Maps.newHashMapWithExpectedSize(5);
        params2.put("materielId", instructionDO.getMaterielId());
//        List<CheckResultDetail2VO> checkProjects = checkProjectService.list3(params2);
//        CheckResultDO resultDO = new CheckResultDO();
//        resultDO.setInstructionId(dto.getAiId());
//        resultDO.setProduct(instructionDO.getMaterielName());
//        resultDO.setInstructionNo(instructionDO.getSerialNo());
//        resultDO.setProductionDate(dto.getIndicateDate());
//        resultDO.setProductId(instructionDO.getMaterielId());
//        resultDO.setDailyId(dto.getId());
//        resultDO.setDailyNo(dto.getAiNo());
//        resultDO.setQualityInspectorId(ShiroUtils.getUserId());
//        resultDO.setQualityInspectorName(ShiroUtils.getUser().getName());
//        resultDO.setInstructionQty(dto.getQualifiedQty());
//        if (!ObjectUtils.isEmpty(checkProjects)){
//            checkResult(checkProjects,resultDO);
//        }
        instructionDO.setResidue(new BigDecimal(0));
        assemblyInstructionService.update(instructionDO);
        return R.ok(result);
    }

    public static void main(String[] args) {
        AssemblyDaily2Dto dto = new AssemblyDaily2Dto();
        ArrayList<String> strings = new ArrayList<>();
        strings.add("234");
        dto.setStartTime2("new Date()");
        AssemblyDailyDto dto1 = new AssemblyDailyDto();
        BeanUtils.copyProperties(dto, dto1);
        System.out.println(dto1);
    }

    /**
     * 生产检察书
     *
     * @param checkResultDetail2VOS
     */
    private void checkResult(List<CheckResultDetail2VO> checkResultDetail2VOS, CheckResultDO resultDO) {
        List<CheckResultDetailDO> detailDOS = new ArrayList<>();
//        resultDO.setQualityInspectorId(ShiroUtils.getUserId());
//        resultDO.setQualityInspectorName(ShiroUtils.getUser().getName());
        resultDO.setStatus(AslConstant.NO);
        resultDO.setDelFlag(AslConstant.NO);
        resultDO.setBillDate(new Date());
        resultDO.setType(AslConstant.YES);


        String prefix = DateFormatUtil.getWorkOrderno(ConstantForMES.CHECK_PLAN_JCCJ, new Date());
        Map<String, Object> params = Maps.newHashMapWithExpectedSize(3);
        params.put("checkNo", prefix);
        params.put("offset", 0);
        params.put("limit", 1);
        List<CheckResultDO> checkResultDOList = checkResultDao.list(params);
        String suffix = null;
        if (checkResultDOList.size() > 0) {
            suffix = checkResultDOList.get(0).getCheckNo();
        }
        resultDO.setCheckNo(DateFormatUtil.getWorkOrderno(prefix, suffix));
        resultDO.setIsChooseShow(2);
        checkResultDao.save(resultDO);
        checkResultDetail2VOS.forEach(check -> {
            CheckResultDetailDO detailDO = new CheckResultDetailDO();
            detailDO.setCheckItemId(check.getCheckItemId());
            detailDO.setCheckTypeId(check.getCheckTypeId());
            detailDO.setSize(check.getSize());
            if (!Constant.QIMI.equals(check.getCheckItem())) {
                detailDO.setSample(check.getSample());
            } else {
                detailDO.setSample(ObjectUtils.isEmpty(resultDO.getInstructionQty()) ? "" : "(※1)=" + resultDO.getInstructionQty());
            }
            detailDO.setCheckItem(check.getCheckItem());
            detailDO.setCheckWay(check.getCheckWay());
            detailDO.setFormula(check.getFormula());
            detailDO.setSpecification(check.getSpecification());
            detailDO.setMainId(resultDO.getId());
            detailDOS.add(detailDO);
        });
        checkResultDetailDao.batchSave(detailDOS);
        checkResultService.sendCheckMessage(resultDO.getId());

    }

    /**
     * 保存组装生产指示信息
     *
     * @date 2019-11-27
     * @author gumingjie
     */
    @Transactional(rollbackFor = Exception.class)
    @EvApiByToken(value = "/apis/AssemblyDaily/save2", method = RequestMethod.POST, apiTitle = "保存成型生产指示信息")
    @ApiOperation("保存组装生产指示信息")
    @ApiImplicitParams({@ApiImplicitParam(name = "indicateDate", value = "日期", dataType = "Date"),
            @ApiImplicitParam(name = "startTime1", value = "", dataType = "String"),
            @ApiImplicitParam(name = "startTime2", value = "", dataType = "String"),
            @ApiImplicitParam(name = "startTime3", value = "", dataType = "String"),
            @ApiImplicitParam(name = "startTime4", value = "", dataType = "String"),
            @ApiImplicitParam(name = "startTime5", value = "", dataType = "String"),
            @ApiImplicitParam(name = "startTime6", value = "", dataType = "String"),
            @ApiImplicitParam(name = "endTime1", value = "", dataType = "String"),
            @ApiImplicitParam(name = "endTime2", value = "", dataType = "String"),
            @ApiImplicitParam(name = "endTime3", value = "", dataType = "String"),
            @ApiImplicitParam(name = "endTime4", value = "", dataType = "String"),
            @ApiImplicitParam(name = "endTime5", value = "", dataType = "String"),
            @ApiImplicitParam(name = "endTime6", value = "", dataType = "String"),
            @ApiImplicitParam(name = "thing1", value = "", dataType = "String"),
            @ApiImplicitParam(name = "thing2", value = "", dataType = "String"),
            @ApiImplicitParam(name = "thing3", value = "", dataType = "String"),
            @ApiImplicitParam(name = "aiId", value = "组装指示主键id", dataType = "int"),
            @ApiImplicitParam(name = "aiNo", value = "组装指示编号", dataType = "String"),
            @ApiImplicitParam(name = "productionQty", value = "生产数量", dataType = "Number"),
            @ApiImplicitParam(name = "qualifiedQty", value = "合格数量", dataType = "Number"),
            @ApiImplicitParam(name = "inspectionQty", value = "不良数量", dataType = "Number"),
            @ApiImplicitParam(name = "badType", value = "不良类型（数据字典维护）", dataType = "init"),
            @ApiImplicitParam(name = "feedingMaterial", value = "（List<>产品代码（子件），产品名称（子件），规格型号，使用数量（EA），不良数量（EA），不良类型，未达要因）", dataType = "JSON"),
            @ApiImplicitParam(name = "specialNoteItem", value = "特记事项", dataType = "String")})
    public R save2(@RequestBody AssemblyDaily2Dto dto) {
        List<AssemblyDailyDetailDtO> dailyDetails = dto.getDailyDetails();
        if (ObjectUtils.isEmpty(dto) || ObjectUtils.isEmpty(dailyDetails)) {
            return R.error("未填写日报详情！");
        }
        for (int i = 0; i < dailyDetails.size(); i++) {
            AssemblyDailyDetailDtO detailDtO = dailyDetails.get(i);
            List<FeedingMaterialDto> feedingMaterial = detailDtO.getFeedingMaterial2();
            if (ObjectUtils.isEmpty(feedingMaterial)) continue;
            String string = JSON.toJSONString(feedingMaterial);
            detailDtO.setFeedingMaterial(string);
            if (ObjectUtils.isEmpty(detailDtO.getProductionQty())) detailDtO.setProductionQty(BigDecimal.ZERO);
            if (ObjectUtils.isEmpty(detailDtO.getQualifiedQty())) detailDtO.setQualifiedQty(BigDecimal.ZERO);
            if (ObjectUtils.isEmpty(detailDtO.getIndicateQty())) detailDtO.setIndicateQty(BigDecimal.ZERO);
            if (ObjectUtils.isEmpty(detailDtO.getInspectionQty())) detailDtO.setInspectionQty(BigDecimal.ZERO);
        }
        return service.save2(dto);
    }

    /**
     * 修改组装日报
     *
     * @param dto
     * @return
     */
    @EvApiByToken(value = "/apis/AssemblyDaily/update2", method = RequestMethod.POST, apiTitle = "修改组装日报")
    @ApiOperation("修改组装日报")
    public R update2(@RequestBody AssemblyDaily3Dto dto) {
        List<AssemblyDailyDetailDtO> dailyDetails = dto.getDailyDetails();
        if (ObjectUtils.isEmpty(dto) || ObjectUtils.isEmpty(dailyDetails)) {
            return R.error("未填写日报详情！");
        }
        for (int i = 0; i < dailyDetails.size(); i++) {
            List<FeedingMaterialDto> feedingMaterial = dailyDetails.get(i).getFeedingMaterial2();
            if (CollectionUtils.isEmpty(feedingMaterial)) continue;
            String string = JSONArray.toJSONString(feedingMaterial);
            dailyDetails.get(i).setFeedingMaterial(string);
        }
        return service.update2(dto);
//        AssemblyDailyDO assemblyDailyDO = service.get(dto.getId());
//        if (AslConstant.AssemblyDaily.PLAN.getType().equals(assemblyDailyDO.getStatus())) {
//            return service.update2(dto);
//        }
//        return R.error("已批准状态不能修改！");
    }

    /**
     * 查看组装日报详情
     *
     * @date 2019-11-27
     * @author gumingjie
     */
    @EvApiByToken(value = "/apis/AssemblyDaily/detail2", method = RequestMethod.GET, apiTitle = "查看组装日报详情")
    @ApiOperation("查看组装日报详情")
    public R detail2(@ApiParam(value = "组装日报Id", required = true) @RequestParam(value = "id", defaultValue = "") Long id) {
        return R.ok(service.getDetailInfo2(id));
    }

    /**
     *组装日报导出
     *
     * @return ApiResult
     */
    @ApiOperation(value = "组装日报导出")
    @GetMapping("/apis/AssemblyDaily/recordExport")
    public void downloadExport(HttpServletResponse response,
                               @ApiParam(value = "主表ID", required = true) @RequestParam(value = "id", defaultValue = "") Long id) {
        service.downloadExport(response,id);
    }

//    /**
//     *组装日报导出
//     *
//     * @return ApiResult
//     */
//    @ApiOperation(value = "组装日报导出")
//    @GetMapping("/apis/exportExcel/checkOut222")
//    public void downloadExport(HttpServletResponse response,
//                               @ApiParam(value = "主表ID", required = true) @RequestParam(value = "id", defaultValue = "") Long id) {
//        service.downloadExport(response,id);
//    }


    /**
     * 查看组装日报详情
     *
     * @date 2019-11-27
     * @author gumingjie
     */
    @EvApiByToken(value = "/apis/AssemblyDaily/detail", method = RequestMethod.POST, apiTitle = "查看组装日报详情")
    @ApiOperation("查看组装日报详情")
    public R detail(@ApiParam(value = "组装日报Id", required = true) @RequestParam(value = "id", defaultValue = "") Long id) {
        return R.ok(service.getDetailInfo(id));
    }

    /**
     * 修改组装日报
     *
     * @param dto
     * @return
     */
    @EvApiByToken(value = "/apis/AssemblyDaily/update", method = RequestMethod.POST, apiTitle = "修改组装日报")
    @ApiOperation("修改组装日报")
    public R update(AssemblyDailyDto dto) {
        AssemblyDailyDO assemblyDailyDO = service.get(dto.getId());
        if (AslConstant.AssemblyDaily.PLAN.getType().equals(assemblyDailyDO.getStatus())) {
            int update = service.update(dto);
            if (update > 0) {
                return R.ok();
            }
            return R.error();
        }
        return R.error("已批准状态不能修改！");
    }

    /**
     * 删除
     */
    @EvApiByToken(value = "/apis/AssemblyDaily/batchRemove", method = RequestMethod.GET, apiTitle = "删除组装日报")
    @ApiOperation("删除组装日报")
    public R batchRemove(@RequestParam("ids") Long[] ids) {
        //前端现在做了限制，一次只能删除一个记录
        AssemblyDaily2Dto assemblyDaily2Dto = dao.getDetailInfo2(ids[0]);
        List<AssemblyDailyDetailDtO> dailyDetails = assemblyDaily2Dto.getDailyDetails();
        if (!ObjectUtils.isEmpty(dailyDetails)) {
            List<Long> aiIds = dailyDetails.stream().map(detail -> detail.getAiId()).collect(Collectors.toList());
            HashMap<String, Object> instructionMap = new HashMap<>();
            instructionMap.put("ids", aiIds);
            List<AssemblyInstructionDO> instructionDOs = assemblyInstructionService.list(instructionMap);
            Map<Long, AssemblyInstructionDO> instructionGroup = instructionDOs.stream().collect(Collectors.toMap(AssemblyInstructionDO::getId, v -> v));
//            instructionDOs = instructionDOs.stream().map(ins -> {
//                ins.setResidue(ins.getQty());
//                return ins;
//            }).collect(Collectors.toList());
            //保存日报详情并反写指示单的剩余数量
            dailyDetails.forEach(detail -> {
                AssemblyInstructionDO instructionDO = instructionGroup.get(detail.getAiId());
                instructionDO.setResidue(instructionDO.getResidue().add(detail.getProductionQty()));
            });
            assemblyInstructionService.batchUpdate(instructionDOs);
        }
        int remove = service.batchRemove(ids);
        if (remove > 0) {
            return R.ok("删除成功");
        }
        return R.error("删除失败");
    }

    /**
     * 删除
     */
    @EvApiByToken(value = "/apis/AssemblyDaily/remove", method = RequestMethod.GET, apiTitle = "删除组装日报")
    @ApiOperation("删除组装日报")
    public R remove(@RequestParam("id") Long id) {
        AssemblyDailyDO assemblyDailyDO = service.get(id);
        if (AslConstant.AssemblyDaily.PLAN.getType().equals(assemblyDailyDO.getStatus())) {
            int remove = service.remove(id);
            if (remove > 0) {
                return R.ok("删除成功");
            }
            return R.error("删除失败");
        }
        return R.error("非计划状态不能删除！");
    }

    /**
     * 审查
     */
    @EvApiByToken(value = "/apis/AssemblyDaily/investigate", method = RequestMethod.GET, apiTitle = "审查组装日报")
    @ApiOperation("审查组装日报")
    public R investigate(@RequestParam("id") Long id, HttpServletRequest request) {

        UserDO userDO = ShiroUtils.getUser();
        if(!ShiroUtils.isUser(AslConstant.WU_ID)){
            return R.error("操作对应人错误，请通知吴江海进行操作");
        }
        AssemblyDailyDO assemblyDailyDO = service.get(id);
        if (AslConstant.AssemblyDaily.PLAN.getType().equals(assemblyDailyDO.getStatus())) {
            return R.error("未提交，不能审查！");
        }
        if (AslConstant.AssemblyDaily.AUDITOR.getType().equals(assemblyDailyDO.getStatus())) {
            return R.error("已审查，不能多次审查！");
        }
        if (AslConstant.AssemblyDaily.APPROVED.getType().equals(assemblyDailyDO.getStatus())) {
            return R.error("该表单已批准！");
        }
        assemblyDailyDO.setStatus(AslConstant.AssemblyDaily.AUDITOR.getType());
        assemblyDailyDO.setAuditorId(userDO.getUserId());
        assemblyDailyDO.setAuditorName(userDO.getName());
        int update = service.update(assemblyDailyDO);
        if (update > 0) {

            String title = "@我裁决的组装日报";
            UserDO user = userService.get(assemblyDailyDO.getCreateBy());
            String content = "您好，"+user.getName()+"提交的组装日报已辅助裁决，请及时裁决";
            JSONObject contentDetail = new JSONObject();
            contentDetail.put("id",id);
            contentDetail.put("url","/jobShop/accessoriesDaily_add?id="+id+"&status="+assemblyDailyDO.getStatus());
            HashMap<String, Object> userMap = new HashMap<>();
            userMap.put("deptId",1979);
            List<UserDO> list = userService.list(userMap);
            List<Long> toUsers = list.stream().filter(userDo -> userDo.getUserId() == 1977).map(UserDO::getUserId).collect(Collectors.toList());

            try {
                noticeService.saveAndSendSocket(title,content, id, contentDetail.toString(),55L,ShiroUtils.getUserId(),toUsers);
            } catch (IOException e) {
                log.error("==============================发送批准组装日报的提醒消息失败。id:"+id);
                throw new RuntimeException(e);
            } catch (ParseException e) {
                log.error("==============================发送批准组装日报的提醒消息失败。id:"+id);
                throw new RuntimeException(e);
            }


            return R.ok();
        }
        return R.error();
    }

    /**
     * 批准
     */
    @EvApiByToken(value = "/apis/AssemblyDaily/ratify", method = RequestMethod.GET, apiTitle = "批准组装日报")
    @ApiOperation("批准组装日报")
    public R ratify(@RequestParam("id") Long id, HttpServletRequest request) {
        UserDO userDO = ShiroUtils.getUser();
        if(!ShiroUtils.isUser(AslConstant.JIN_ID)){
            return R.error("操作对应人错误，请通知金炯德进行操作");
        }
        AssemblyDailyDO assemblyDailyDO = service.get(id);
        if (AslConstant.AssemblyDaily.PLAN.getType().equals(assemblyDailyDO.getStatus())) {
            return R.error("未提交，不能批准！");
        }
        if (AslConstant.AssemblyDaily.SUBMITTED.getType().equals(assemblyDailyDO.getStatus())) {
            return R.error("未审查，不能批准！");
        }
        if (AslConstant.AssemblyDaily.APPROVED.getType().equals(assemblyDailyDO.getStatus())) {
            return R.error("已批准，不能多次批准！");
        }
        assemblyDailyDO.setStatus(AslConstant.MoldingDailyStatus.APPROVED.getType());
        assemblyDailyDO.setApproverId(userDO.getUserId());
        assemblyDailyDO.setApproverName(userDO.getName());
        service.syncSaveToK32(assemblyDailyDO);
        int update = service.update(assemblyDailyDO);
        return R.ok();
//        if (service.syncSaveToK3(assemblyDailyDO) > 0){
//            int update = service.update(assemblyDailyDO);
//            if (update > 0) {
//                //将打码枪信息保存至
//                moldingBarcodeService.creatMoldingBarcode(id,assemblyDailyDO.getAiId(),assemblyDailyDO.getQualifiedQty(),0,2,assemblyDailyDO.getCreateTime());
//                service.update(assemblyDailyDO);
//                return R.ok();
//            }
//        }
//        return R.error();

//        int update = service.update(assemblyDailyDO);
//        return R.ok();
    }


    /**
     * 提交
     */
    @EvApiByToken(value = "/apis/AssemblyDaily/submitted", method = RequestMethod.POST, apiTitle = "提交组装日报")
    @ApiOperation("提交组装日报")
    @Transactional(rollbackFor = Exception.class)
    public R submitted(@RequestBody AssemblyDaily3Dto dto) {
        HashMap<String, Object> userMap = new HashMap<>();
        List<UserDO> list = userService.list(userMap);
        List<Long> toUsers = list.stream().filter(userDO -> userDO.getUserId()==272).map(UserDO::getUserId).collect(Collectors.toList());
        String title = "@我需要审查的组装日报";
        if(ObjectUtils.isEmpty(dto.getId())){
            AssemblyDaily2Dto dto2 = new AssemblyDaily2Dto();
            BeanUtils.copyProperties(dto,dto2);
            dto2.setStatus(AslConstant.AssemblyDaily.SUBMITTED.getType());
            R r = this.save2(dto2);
            AssemblyDailyDO assemblyDailyDO = service.get(dto2.getId());
            UserDO user = userService.get(assemblyDailyDO.getCreateBy());


            String content = "您好，"+user.getName()+"的组装日报填写完成，请及时辅助裁决";
            JSONObject contentDetail = new JSONObject();
            contentDetail.put("id",dto2.getId());
            contentDetail.put("url","/jobShop/accessoriesDaily_add?id="+assemblyDailyDO.getId()+"&status="+assemblyDailyDO.getStatus());
            try {
                noticeService.saveAndSendSocket(title,content, dto2.getId(), contentDetail.toString(),55L,ShiroUtils.getUserId(),toUsers);
            } catch (IOException e) {
                log.error("==============================发送辅助裁决组装日报的提醒消息失败。id:"+dto.getId());
                throw new RuntimeException(e);
            } catch (ParseException e) {
                log.error("==============================发送辅助裁决组装日报的提醒消息失败。id:"+dto.getId());
                throw new RuntimeException(e);
            }
            return r;
        }else{
            if (AslConstant.AssemblyDaily.SUBMITTED.getType().equals(dto.getStatus())) {
                return R.error("已提交，不能多次提交！");
            }
            if (AslConstant.AssemblyDaily.AUDITOR.getType().equals(dto.getStatus())) {
                return R.error("已审查，不能提交！");
            }
            if (AslConstant.AssemblyDaily.APPROVED.getType().equals(dto.getStatus())) {
                return R.error("已批准，不能提交！");
            }
            UserDO user = userService.get(dto.getCreateBy());
            dto.setStatus(AslConstant.AssemblyDaily.SUBMITTED.getType());
            String content = "您好，"+user.getName()+"的组装日报填写完成，请及时辅助裁决";
            JSONObject contentDetail = new JSONObject();
            contentDetail.put("id",dto.getId());
            contentDetail.put("url","/jobShop/accessoriesDaily_add?id="+dto.getId()+"&status="+dto.getStatus());
            try {
                noticeService.saveAndSendSocket(title,content, dto.getId(), contentDetail.toString(),55L,ShiroUtils.getUserId(),toUsers);
            } catch (IOException e) {
                log.error("==============================发送辅助裁决组装日报的提醒消息失败。id:"+dto.getId());
                throw new RuntimeException(e);
            } catch (ParseException e) {
                log.error("==============================发送辅助裁决组装日报的提醒消息失败。id:"+dto.getId());
                throw new RuntimeException(e);
            }
            return this.update2(dto);
        }


    }

    @EvApiByToken(value = "/apis/AssemblyDaily/withdraw", method = RequestMethod.GET, apiTitle = "撤回组装日报")
    @ApiOperation("撤回组装日报")
    @Transactional(rollbackFor = Exception.class)
    public R withdraw(@RequestParam("id") Long id){
        UserDO userDo = ShiroUtils.getUser();
        AssemblyDailyDO assemblyDailyDO = service.get(id);
        if (AslConstant.AssemblyDaily.PLAN.getType().equals(assemblyDailyDO.getStatus())) {
            return R.error("未提交，不能撤回！");
        }
        if (AslConstant.AssemblyDaily.AUDITOR.getType().equals(assemblyDailyDO.getStatus())) {
            return R.error("已审查，不能撤回！");
        }
        if (AslConstant.AssemblyDaily.APPROVED.getType().equals(assemblyDailyDO.getStatus())) {
            return R.error("已批准，不能撤回！");
        }
        if(!ObjectUtil.equal(userDo.getUserId(),assemblyDailyDO.getCreateBy())){
            return R.error("不是日报提交人,无法进行撤回");
        }
        assemblyDailyDO.setStatus(AslConstant.AssemblyDaily.PLAN.getType());
        Integer update = service.update(assemblyDailyDO);
        if(update>0){
            JSONObject contentDetail = new JSONObject();
            contentDetail.put("id",assemblyDailyDO.getId());
            contentDetail.put("url","/jobShop/accessoriesDaily_add?id="+assemblyDailyDO.getId()+"&status="+AslConstant.AssemblyDaily.SUBMITTED.getType());
            Map<String,Object> map = new HashMap<>();
            map.put("contentDetail",contentDetail.toString());
            map.put("billId",assemblyDailyDO.getId());
            noticeService.removeForMap(map);
            return R.ok();
        }
        return R.error();
    }

    /**
     * 驳回组装日报
     */
    @EvApiByToken(value = "/apis/AssemblyDaily/overrule", method = RequestMethod.GET, apiTitle = "驳回组装日报")
    @ApiOperation("驳回组装日报")
    @Transactional(rollbackFor = Exception.class)
    public R overrule(@RequestParam("id") Long id) {
        UserDO userDo = ShiroUtils.getUser();
        if(!ShiroUtils.isUser(AslConstant.WU_ID)){
            return R.error("操作对应人错误，请通知吴江海进行操作");
        }
        AssemblyDailyDO assemblyDailyDO = service.get(id);
        if (AslConstant.AssemblyDaily.PLAN.getType().equals(assemblyDailyDO.getStatus())) {
            return R.error("未提交，不能驳回！");
        }
        if (AslConstant.AssemblyDaily.AUDITOR.getType().equals(assemblyDailyDO.getStatus())) {
            return R.error("已审查，不能驳回！");
        }
        if (AslConstant.AssemblyDaily.APPROVED.getType().equals(assemblyDailyDO.getStatus())) {
            return R.error("已批准，不能驳回！");
        }
        assemblyDailyDO.setStatus(AslConstant.AssemblyDaily.PLAN.getType());
        assemblyDailyDO.setAuditorName("");
        assemblyDailyDO.setAuditorId(0L);
        Integer update = service.update(assemblyDailyDO);
        if (update > 0) {
            UserDO user = userService.get(assemblyDailyDO.getCreateBy());
            String title = "@我需要修改的组装日报";
            String content = "您好，"+user.getName()+"的组装日报被驳回，请及时修改";
            JSONObject contentDetail = new JSONObject();
            contentDetail.put("id",id);
            contentDetail.put("url","/jobShop/accessoriesDaily_add?id="+id+"&status="+assemblyDailyDO.getStatus());
            List<Long> toUsers = new ArrayList<>();
            toUsers.add(user.getUserId());

            try {
                noticeService.saveAndSendSocket(title,content, id, contentDetail.toString(),55L,ShiroUtils.getUserId(),toUsers);
            } catch (IOException e) {
                log.error("==============================发送驳回组装日报的提醒消息失败。id:"+id);
                throw new RuntimeException(e);
            } catch (ParseException e) {
                log.error("==============================发送驳回组装日报的提醒消息失败。id:"+id);
                throw new RuntimeException(e);
            }

            return R.ok();
        }
        return R.error();
    }

    /**
     * 反辅助裁决
     */
    @EvApiByToken(value = "/apis/AssemblyDaily/antiInvestigate", method = RequestMethod.GET, apiTitle = "反辅助裁决组装日报")
    @ApiOperation("反辅助裁决组装日报")
    @Transactional(rollbackFor = Exception.class)
    public R antiInvestigate(@RequestParam("id") Long id) {
        if(!ShiroUtils.isUser(AslConstant.JIN_ID)){
            return R.error("操作对应人错误，请通知金炯德进行操作");
        }
        AssemblyDailyDO assemblyDailyDO = service.get(id);
        if (AslConstant.AssemblyDaily.PLAN.getType().equals(assemblyDailyDO.getStatus())) {
            return R.error("未提交，不能反辅助裁决！");
        }
        if (AslConstant.AssemblyDaily.SUBMITTED.getType().equals(assemblyDailyDO.getStatus())) {
            return R.error("未审查，不能反辅助裁决！");
        }
        if (AslConstant.AssemblyDaily.APPROVED.getType().equals(assemblyDailyDO.getStatus())) {
            return R.error("已批准，不能反辅助裁决！");
        }
        assemblyDailyDO.setStatus(AslConstant.AssemblyDaily.SUBMITTED.getType());
        Integer update = service.update(assemblyDailyDO);
        if (update > 0) {

            String title = "@我被反审的组装日报";
            UserDO user = userService.get(assemblyDailyDO.getCreateBy());
            String content = "您好，"+user.getName()+"提交的组装日报被反审，请及时修正";
            JSONObject contentDetail = new JSONObject();
            contentDetail.put("id",id);
            contentDetail.put("url","/jobShop/accessoriesDaily_add?id="+id+"&status="+assemblyDailyDO.getStatus());
            HashMap<String, Object> userMap = new HashMap<>();
            userMap.put("deptId",346);
            List<UserDO> list = userService.list(userMap);
            List<Long> toUsers = list.stream().filter(userDO -> userDO.getUserId()==272).map(UserDO::getUserId).collect(Collectors.toList());

            try {
                noticeService.saveAndSendSocket(title,content, id, contentDetail.toString(),55L,ShiroUtils.getUserId(),toUsers);
            } catch (IOException e) {
                log.error("==============================发送修改的组装日报的提醒消息失败。id:"+id);
                throw new RuntimeException(e);
            } catch (ParseException e) {
                log.error("==============================发送修改的组装日报的提醒消息失败。id:"+id);
                throw new RuntimeException(e);
            }

            return R.ok();
        }
        return R.error();
    }

    /**
     * 查看组装日报分页列表
     *
     * @param pageno
     * @param pagesize
     * @param delFlag
     * @param aiNo
     * @param materielName
     * @param indicateDateStart
     * @param indicateDateEnd
     * @return
     */
    @EvApiByToken(value = "/apis/AssemblyDaily/list", method = RequestMethod.POST, apiTitle = "查看组装日报分页列表")
    @ApiOperation("查看组装日报分页列表")
    public R list(@ApiParam(value = "当前第几页", required = true) @RequestParam(value = "pageno", defaultValue = "1") int pageno,
                  @ApiParam(value = "一页多少条", required = true) @RequestParam(value = "pagesize", defaultValue = "20") int pagesize,
                  @ApiParam(value = "刪除状态") @RequestParam(value = "delFlag", defaultValue = "", required = false) Integer delFlag,
                  @ApiParam(value = "指示编号") @RequestParam(value = "aiNo", defaultValue = "", required = false) String aiNo,
                  @ApiParam(value = "状态") @RequestParam(value = "status", defaultValue = "", required = false) Integer status,
                  @ApiParam(value = "品名") @RequestParam(value = "materielName", defaultValue = "", required = false) String materielName,
                  @ApiParam(value = "日期的起始时间") @RequestParam(value = "indicateDateStart", defaultValue = "", required = false) Date indicateDateStart,
                  @ApiParam(value = "日期的结束时间") @RequestParam(value = "indicateDateEnd", defaultValue = "", required = false) Date indicateDateEnd) {

        Map<String, Object> params = Maps.newHashMapWithExpectedSize(8);
        params.put("offset", (pageno - 1) * pagesize);
        params.put("limit", pagesize);
        params.put("delFlag", delFlag);
        params.put("status", status);
        params.put("aiNo", aiNo);
        params.put("materielName", materielName);
        params.put("indicateDateStart", indicateDateStart);
        params.put("indicateDateEnd", indicateDateEnd);

        Map<String, Object> results = Maps.newHashMapWithExpectedSize(1);
        List<Map<String, Object>> data = service.listForMap(params);

        if (data.size() > 0) {
            int total = service.countForMap(params);

            params.remove("offset");
            params.remove("limit");
            List<Map<String, Object>> data2 = service.listForMap(params);
            BigDecimal indicateQtyTotal = BigDecimal.ZERO;
            BigDecimal productionQtyTotal = BigDecimal.ZERO;
            BigDecimal qualifiedQtyTotal = BigDecimal.ZERO;
            BigDecimal inspectionQtyTotal = BigDecimal.ZERO;
            for (Map<String, Object> map : data2) {
                indicateQtyTotal = indicateQtyTotal
                        .add(new BigDecimal(String
                                .valueOf(map.get("indicateQty") != null ? map.get("indicateQty") : "0")))
                        .setScale(2, BigDecimal.ROUND_HALF_UP);
                productionQtyTotal = productionQtyTotal
                        .add(new BigDecimal(String.valueOf(
                                map.get("productionQty") != null ? map.get("productionQty") : "0")))
                        .setScale(2, BigDecimal.ROUND_HALF_UP);
                qualifiedQtyTotal = qualifiedQtyTotal
                        .add(new BigDecimal(String
                                .valueOf(map.get("qualifiedQty") != null ? map.get("qualifiedQty") : "0")))
                        .setScale(2, BigDecimal.ROUND_HALF_UP);
                inspectionQtyTotal = inspectionQtyTotal
                        .add(new BigDecimal(String.valueOf(
                                map.get("inspectionQty") != null ? map.get("inspectionQty") : "0")))
                        .setScale(2, BigDecimal.ROUND_HALF_UP);
            }

            for (Map<String, Object> map : data) {
//                map.put("indicateDate", DateUtils.format((Date) map.get("indicateDate")));
                map.put("startDate", ObjectUtil.isEmpty(map.get("startDate")) ? null : DateUtils.format((Date) map.get("startDate"), "yyyy-MM-dd HH:mm:ss"));
                map.put("endDate", ObjectUtil.isEmpty(map.get("endDate")) ? null : DateUtils.format((Date) map.get("endDate"), "yyyy-MM-dd HH:mm:ss"));
            }

            Map<String, Object> result = Maps.newHashMapWithExpectedSize(4);
            result.put("data", new DsResultResponse(pageno, pagesize, total, data));

            result.put("indicateQtyTotal", indicateQtyTotal);
            result.put("productionQtyTotal", productionQtyTotal);
            result.put("qualifiedQtyTotal", qualifiedQtyTotal);
            result.put("inspectionQtyTotal", inspectionQtyTotal);
            results.put("data", result);
        }
        return R.ok(results);
    }

    @EvApiByToken(value = "/apis/AssemblyDaily/list/exportExcel", method = RequestMethod.GET, apiTitle = "成型生产指示分页列表(导出)")
    @ApiOperation("成型生产指示分页列表(导出)")
    public void exportExcel(@ApiParam(value = "刪除状态") @RequestParam(value = "delFlag", defaultValue = "", required = false) Integer delFlag,
                            @ApiParam(value = "指示编号") @RequestParam(value = "aiNo", defaultValue = "", required = false) String aiNo,
                            @ApiParam(value = "品名") @RequestParam(value = "materielName", defaultValue = "", required = false) String materielName,
                            @ApiParam(value = "日期的起始时间") @RequestParam(value = "indicateDateStart", defaultValue = "", required = false) Date indicateDateStart,
                            @ApiParam(value = "日期的结束时间") @RequestParam(value = "indicateDateEnd", defaultValue = "", required = false) Date indicateDateEnd,
                            HttpServletRequest request, HttpServletResponse response,
                            ModelMap modelMap) {
        Map<String, Object> params = Maps.newHashMapWithExpectedSize(5);
        params.put("delFlag", delFlag);
        params.put("aiNo", aiNo);
        params.put("materielName", materielName);
        params.put("indicateDateStart", indicateDateStart);
        params.put("indicateDateEnd", indicateDateEnd);
        List<Map<String, Object>> data = service.listForMap(params);
        if (!CollectionUtils.isEmpty(data)) {

            BigDecimal indicateQtyTotal = BigDecimal.ZERO;
            BigDecimal productionQtyTotal = BigDecimal.ZERO;
            BigDecimal qualifiedQtyTotal = BigDecimal.ZERO;
            BigDecimal inspectionQtyTotal = BigDecimal.ZERO;
            for (Map<String, Object> map : data) {
                map.put("indicateDateString", DateUtils.format((Date) map.get("indicateDate")));

                indicateQtyTotal = indicateQtyTotal
                        .add(new BigDecimal(String
                                .valueOf(map.get("indicateQty") != null ? map.get("indicateQty") : "0")))
                        .setScale(2, BigDecimal.ROUND_HALF_UP);
                productionQtyTotal = productionQtyTotal
                        .add(new BigDecimal(String.valueOf(
                                map.get("productionQty") != null ? map.get("productionQty") : "0")))
                        .setScale(2, BigDecimal.ROUND_HALF_UP);
                qualifiedQtyTotal = qualifiedQtyTotal
                        .add(new BigDecimal(String
                                .valueOf(map.get("qualifiedQty") != null ? map.get("qualifiedQty") : "0")))
                        .setScale(2, BigDecimal.ROUND_HALF_UP);
                inspectionQtyTotal = inspectionQtyTotal
                        .add(new BigDecimal(String.valueOf(
                                map.get("inspectionQty") != null ? map.get("inspectionQty") : "0")))
                        .setScale(2, BigDecimal.ROUND_HALF_UP);
            }

            Map<String, Object> map = Maps.newHashMap();
            map.put("list", JSONUtils.format(data));
            map.put("indicateQtyTotal", indicateQtyTotal);
            map.put("productionQtyTotal", productionQtyTotal);
            map.put("qualifiedQtyTotal", qualifiedQtyTotal);
            map.put("inspectionQtyTotal", inspectionQtyTotal);

            ClassPathResource classPathResource = new ClassPathResource("poi/assembly_daily.xlsx");
            TemplateExportParams result = new TemplateExportParams(classPathResource.getPath());
            modelMap.put(TemplateExcelConstants.FILE_NAME, "组装日报");
            modelMap.put(TemplateExcelConstants.PARAMS, result);
            modelMap.put(TemplateExcelConstants.MAP_DATA, map);
            PoiBaseView.render(modelMap, request, response,
                    TemplateExcelConstants.EASYPOI_TEMPLATE_EXCEL_VIEW);
        }
    }
}
